package com.rainng.coursesystem.module.system.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.rainng.coursesystem.base.api.ApiError;
import com.rainng.coursesystem.base.api.dto.BaseIdReqDTO;
import com.rainng.coursesystem.base.api.dto.PagingReqDTO;
import com.rainng.coursesystem.base.constant.Constant;
import com.rainng.coursesystem.base.exception.ServiceException;
import com.rainng.coursesystem.base.utils.BeanMapper;
import com.rainng.coursesystem.base.utils.jwt.JwtUtils;
import com.rainng.coursesystem.base.utils.passwd.PassHandler;
import com.rainng.coursesystem.base.utils.passwd.PassInfo;
import com.rainng.coursesystem.base.utils.service.RedisService;
import com.rainng.coursesystem.module.system.dto.request.SysUserLoginDto;
import com.rainng.coursesystem.module.system.dto.request.SysUserQueryReqDTO;
import com.rainng.coursesystem.module.system.dto.request.SysUserSaveReqDTO;
import com.rainng.coursesystem.module.system.dto.response.SysUserBaseResDTO;
import com.rainng.coursesystem.module.system.dto.response.SysUserResBaseDTO;
import com.rainng.coursesystem.module.system.dto.response.SysUserResDTO;
import com.rainng.coursesystem.module.system.entity.SysGroup;
import com.rainng.coursesystem.module.system.entity.SysRole;
import com.rainng.coursesystem.module.system.entity.SysUser;
import com.rainng.coursesystem.module.system.mapper.SysUserMapper;
import com.rainng.coursesystem.module.system.service.SysGroupService;
import com.rainng.coursesystem.module.system.service.SysRoleService;
import com.rainng.coursesystem.module.system.service.SysUserRoleService;
import com.rainng.coursesystem.module.system.service.SysUserService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements SysUserService {


//    @Autowired
    private RedisService redisService;

    @Autowired
    private SysUserRoleService sysUserRoleService;

    @Autowired
    SysRoleService sysRoleService;

    @Autowired
    SysGroupService sysGroupService;
    @Autowired
    HttpServletRequest request;


    @Override
    public String getUserName() {
        try {
            return JwtUtils.getUsername(request.getHeader("token"));
        }catch (Exception e){
            throw new ServiceException("通过token获取用户名错误!");
        }
    }
    @Override
    public SysUserResDTO login(SysUserLoginDto reqDto) {
        //后期引入校验码
        QueryWrapper<SysUser> eq = new QueryWrapper<>();
        eq.lambda().eq(SysUser::getUserName,reqDto.getUsername());
        SysUser user = this.getOne(eq);
        return this.checkLogin(user,reqDto.getPassword());

    }


//    public String getRoleId(String roleName){
//        QueryWrapper<SysRole> wrapper = new QueryWrapper<>();
//        wrapper.lambda().eq(SysRole::getRoleName,roleName);
//        SysRole sysRole = sysRoleService.getOne(wrapper);
//        return sysRole.getId();
//    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void save(SysUserSaveReqDTO reqDTO) {
//        if (StringUtils.isBlank(reqDTO.getRoleId())){
//            throw new ServiceException("角色为空");
//        }
//        QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
//        queryWrapper.lambda().eq(SysUser::getUserName,reqDTO.getUserName());
//        if (!StringUtils.isBlank(reqDTO.getId())){
//            queryWrapper.lambda().ne(SysUser::getId,reqDTO.getId());
//        }
//        int count = this.count(queryWrapper);
//        if (count > 0){
//            throw new ServiceException("登录名不能重复!");
//        }
//        SysUser user;
//        String id = IdWorker.getIdStr();
//        if (StringUtils.isBlank(reqDTO.getId())){
//            user = new SysUser();
//            BeanMapper.copy(reqDTO,user);
//            user.setCreateBy(getUserName());
//            user.setId(id);
//            user.setCreateTime(new Date());
//        }else {
//            user = this.getById(reqDTO.getId());
//            BeanMapper.copy(reqDTO,user);
//            user.setUpdateBy(getUserName());
//            user.setUpdateTime(new Date());
//        }
//        if(!StringUtils.isBlank(reqDTO.getPassword())){
//            PassInfo pass = PassHandler.buildPassword(reqDTO.getPassword());
//            user.setPassword(pass.getPassword());
//            user.setSalt(pass.getSalt());
//        }
//        //更新用户表
//        this.saveOrUpdate(user);
    }

    @Override
    public IPage<SysUserResDTO> paging(PagingReqDTO<SysUserQueryReqDTO> reqDTO) {
        IPage<SysUserResDTO> pageData = baseMapper.paging(reqDTO.toPage(),reqDTO.getParams());
        return pageData;
    }

    @Override
    public List<SysUserResBaseDTO> listAllUser() {
        List<SysUserResBaseDTO> res = baseMapper.listAllUsers();
        return res;
    }

    @Override
    public SysUserResDTO detail(BaseIdReqDTO reqDTO) {
        if (reqDTO.getId() != null){
            SysUser user = this.getById(reqDTO.getId());
            user.setPassword(null);
            SysUserResDTO resDTO = new SysUserResDTO();
            BeanMapper.copy(user,resDTO);
            //获取角色name
            SysRole role = sysRoleService.getOne(new LambdaQueryWrapper<SysRole>().eq(SysRole::getId,user.getRoleId()));
            if (role!=null){
                resDTO.setRoleName(role.getRoleName());
            }
            //获取组别name
            SysGroup group = sysGroupService.getOne(new LambdaQueryWrapper<SysGroup>().eq(SysGroup::getId,user.getGroupId()));
            if (group!=null){
                resDTO.setGroupName(group.getGroupName());
            }
            return resDTO;
        }
        return new SysUserResDTO();
    }

    @Override
    public List<SysUserBaseResDTO> getList() {
        List<SysUser> list = this.list();
        List<SysUserBaseResDTO> collect = new ArrayList<>();
        if (list!=null){
            collect = list.stream().map(user -> new SysUserBaseResDTO(user.getId(), user.getUserName())).collect(Collectors.toList());
        }
        return collect;
    }

    @Override
    public void delete(List<String> ids) {
        QueryWrapper<SysUser> wrapper = new QueryWrapper<>();
        wrapper.lambda().in(SysUser::getId,ids);

        List<SysUser> users = this.list(wrapper);
        List<String> roleList = users.stream().map(user -> user.getRoleId()).distinct().collect(Collectors.toList());
        //查找要删除的角色级别是否小于当前操作用户的角色等级
        QueryWrapper<SysRole> roleWrapper = new QueryWrapper<>();
//        Integer roleLevel = sysRoleService.getCurrentRoleLevel();
//        roleWrapper.lambda().in(SysRole::getId,roleList).lt(SysRole::getRoleLevel,roleLevel);
        //同级别也不能删除
        int count = sysRoleService.count(roleWrapper);

        if (count < roleList.size()){
            throw new ServiceException("删除用户角色级别必须小于自身等级!");
        }
        this.removeByIds(ids);
    }

    @Override
    public SysUserResDTO getInfo(String token) {
        String key = Constant.USER_NAME_KEY + getUserName();
        JSONObject json = redisService.getJson(key);
        if (json == null){
            return new SysUserResDTO();
        }
        SysUserResDTO resDTO = JSONObject.toJavaObject(json, SysUserResDTO.class);
        return resDTO;
    }

    @Override
    public List<SysUserBaseResDTO> getListUserByRole() {
        SysRole role = sysRoleService.getOne(new LambdaQueryWrapper<SysRole>().eq(SysRole::getRoleName, "主检"));
        if (role == null) {
            throw new ServiceException("没有主检角色");
        }
        //查找和自身一组的主检角色
        SysUserResDTO sysUserResDTO = this.getCurrentUser();
        SysRole sysRole = sysRoleService.getById(sysUserResDTO.getRoleId());
        if (sysRole.getRoleName().equals("超级管理员")){
            List<SysUser> userDTOS = this.list();
            List<SysUserBaseResDTO> collect = userDTOS.stream()
                    .filter(user -> !user.getUserName().equals("admin"))
                    .map(e->new SysUserBaseResDTO(e.getId(),e.getRealName()))
                    .collect(Collectors.toList());
            return collect;
        }else {
            LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(SysUser::getGroupId,sysUserResDTO.getGroupId());
            List<SysUser> userDTOS = baseMapper.selectList(queryWrapper);
            List<SysUserBaseResDTO> collect = userDTOS.stream()
                    .filter(user -> !user.getUserName().equals("admin"))
                    .map(e->new SysUserBaseResDTO(e.getId(),e.getRealName()))
                    .collect(Collectors.toList());
            return collect;
        }
    }

    @Override
    public SysUserResDTO getCurrentUser() {
        String key = Constant.USER_NAME_KEY + getUserName();
        JSONObject json = redisService.getJson(key);
        if (json == null){
            return new SysUserResDTO();
        }
        SysUserResDTO resDTO = JSONObject.toJavaObject(json, SysUserResDTO.class);
        return resDTO;
    }

    private SysUserResDTO checkLogin(SysUser user, String password) {
        if (user == null){
            throw new ServiceException(ApiError.ERROR_90010001);
        }
//        if (!StringUtils.isBlank(password)){
//            boolean pass = PassHandler.checkPass(password, user.getSalt(), user.getPassword());
//            if (!pass){
//                throw new ServiceException(ApiError.ERROR_90010002);
//            }
//        }
        return this.setToken(user);
    }

    private SysUserResDTO setToken(SysUser user) {
        // 获取一个用户登录的信息
        String key = Constant.USER_NAME_KEY + user.getUserName();
        String json = redisService.getString(key);
        if (!StringUtils.isBlank(json)) {
            // 删除旧的会话
            redisService.del(key);
        }
        SysUserResDTO respDTO = new SysUserResDTO();
        BeanMapper.copy(user, respDTO);

        //根据用户生成token
        String token = JwtUtils.sign(user.getUserName());
        respDTO.setToken(token);

        //设置redis缓存
        redisService.set(key, JSON.toJSONString(respDTO),60*60*24L);
        return respDTO;
    }

}
